<?php

abstract class BaseConfig extends ConfigAppModel
{
	var $name = 'BaseConfig';
	var $useTable = 'config';
	var $cache = false;
	//use  allowMultipleValue to allow multiple insert for a particular key
 	var $fieldProperties = array();
 	var $cacheTime = '+10 hours';
	function afterInitialize()
	{
		$this->setScope(array(
			$this->alias.'.key like' => $this->alias.'.%'
		));
		
		parent::afterInitialize();
	}
	
	/**
	 * Initialized configuration - stores into config's static object
	 */
	function init()
	{
		$configurations = false;
		$cacheKey  = $this->getCacheKey();
		
		GigaCache::set(array('path'=>CACHE,'duration' => $this->cacheTime));
		if($this->cache)
		{
			$configurations = GigaCache::read($cacheKey);
		};
		if(!is_array($configurations))
		{
			$configurations = $this->find('all');
			GigaCache::set(array('path'=>CACHE,'duration' => $this->cacheTime));
			GigaCache::write($cacheKey , $configurations);
		}
		$writableConfig = Set::combine($configurations, '{n}.'.$this->alias.'.key',
			 '{n}.'.$this->alias.'.value');
		$defaultValues = array();
		foreach($this->getFields() as $field)
		{
			$keyName = $this->getKeyName($field);
			$default = null;
			$default=$this->getFieldProperty($field,'default');
			$defaultValues[$keyName] = $default;
		}
		//merge with default values
		$writableConfig = am($defaultValues,$writableConfig);
		foreach($writableConfig as $key => $val)
		{
			Configure::write($key, $val);
		}
	}
	
	function save($data = null, $validate = true, $fieldList = array())
	{
		
		if($validate == true)
		{
			$this->set($data);
			if($this->validates()!== true)
			{
				return false;
			}
		}
		
		$newData = array();
		$tmp = Utility::dotNotation($data);
		foreach($tmp as $key => $val)
		{
			$newData[$this->alias] = array(
				'key' => $key,
				'value' => $val
			);
			parent::create();
			//check whether to insert row or update row
			//depeding on configurtion set. 
			$fieldName = $this->getFieldNameFromKey($key);
			if($this->getFieldProperty($fieldName,'allowMultipleValue')!==true)
			{
				$id = $this->field('id',array('key'=>$key));
				if($id)
				{
					$this->id = $id;
				}
			}
			if(!parent::save($newData, false, $fieldList))
			{
				return false;
			}
		}
		//delete cache.
		GigaCache::set(array('path'=>CACHE));
		GigaCache::delete($this->getCacheKey());
		$this->init();
		return true;
	}
	/**
	 * Reads configuration for a given key
	 * @param $key
	 */
	function readConfig($key)
	{
		if(is_null(Configure::read($this->alias))==true)
		{
			$this->init();
		}
		$configName = $this->getKeyName($key);
		return Configure::read($configName);
	}
	// returns FormHelper friendly data for auto-population from controllers
	function getKeyValuePairs()
	{
		$data = array();
		$data[$this->alias] = array();
		$configs = $this->find('all');
		$defaults = array();
		//set default values
		foreach($this->getFields() as $field)
		{
			$default=$this->getFieldProperty($field,'default');
			$defaults[$field] = $default;
		}
		foreach($configs as $config)
		{
			$field = $this->getFieldNameFromKey($config[$this->alias]['key']);
			$data[$this->alias][$field] = $config[$this->alias]['value'];
		}
		$data[$this->alias] = am($defaults,$data[$this->alias]);
		return $data;
	}
	/**
	 * return field name from keyname
	 * @param $key
	 */
	function getFieldNameFromKey($key)
	{
		$fieldNameArr = explode('.',$key);
		array_shift($fieldNameArr);
		$fieldName = implode('.',$fieldNameArr);
		return $fieldName;
	}
	/**
	 * return key name for a field based on the config model name
	 * @param unknown_type $key
	 */
	function getKeyName($field)
	{
		return $this->alias.'.'.$field;
	}
	
	protected function getCacheKey()
	{
		return low($this->alias.'Config');
	}
	
	function afterSave($created)
	{
		return parent::afterSave($created);
	}
	function getConfigs()
	{
		if(is_null(Configure::read($this->alias))==true)
		{
			$this->init();
		}
		return Configure::read($this->alias);
	}
	
	/**
	 * Handy function to handle individual configuration updates in real-time.
	 * Usage: cri('GeneralConfig')->saveKey('mykey', 'val');
	 * 
	 * @param $key
	 * @param $value
	 */
	function saveKey($key, $value)
	{
		$key = $this->getKeyName($key);
		$newRecord = array($this->alias => array(
			'key' => $key,
			'value' => $value
		));
		$id = $this->field('id',array('key'=>$key));
		if($id)
		{
			$this->id = $id;
		}
		else
		{
			parent::create();
		}
		
		if(!parent::save($newRecord, false, array()))
		{
			return false;
		}
		//delete cache.
		GigaCache::set(array('path'=>CACHE));
		GigaCache::delete($this->getCacheKey());
		$this->init();
		return true;
	}
}

?>